//
//  FPUserModel.m
//  FinanceProject
//
//  Created by 陈显摆 on 2025/1/15.
//

#import "FPUserModel.h"



@implementation FPProducts

+ (JSONKeyMapper *)keyMapper {
    
    return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"ID" : @"id"}];
}

+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    
    return YES;
}

//+ (BOOL)supportsSecureCoding {
// 
//    return YES;
//}
//
//static id _sharedProducts;
//+ (instancetype)allocWithZone:(struct _NSZone *)zone {
//    
//    @synchronized(self) {
//        
//        if (_sharedProducts == nil) {
//            
//            _sharedProducts = [super allocWithZone:zone];
//        }
//    }
//    return _sharedProducts;
//}
//
//+ (instancetype)sharedProducts {
//    
//    @synchronized(self){
//        
//        if(_sharedProducts == nil){
//            
//            _sharedProducts = [[self alloc] init];
//        }
//    }
//    return _sharedProducts;
//}
//
//- (id)copyWithZone:(NSZone *)zone {
//    
//    return _sharedProducts;
//}
//
//
//- (void)encodeWithCoder:(NSCoder *)aCoder {
//    
//    unsigned int count;
//    Ivar *ivar = class_copyIvarList([self class], &count);
//   
//    for (int i = 0; i < count; i ++) {
//    
//        Ivar iva = ivar[i];
//        const char *name = ivar_getName(iva);
//        NSString *strName = [NSString stringWithUTF8String:name];
//        //利用KVC取值
//        id value = [self valueForKey:strName];
//        [aCoder encodeObject:value forKey:strName];
//    }
//    free(ivar);
//}
//
//- (instancetype)initWithCoder:(NSCoder *)aDecoder {
//    
//    if (self = [super init]) {
//        unsigned int count = 0;
//        Ivar *ivar = class_copyIvarList([self class], &count);
//        for (int i = 0; i < count; i++) {
//            Ivar iva = ivar[i];
//            const char *name = ivar_getName(iva);
//            NSString *strName = [NSString stringWithUTF8String:name];
//            //进行解档取值
//            id value = [aDecoder decodeObjectForKey:strName];
//            //利用KVC对属性赋值
//            [self setValue:value forKey:strName];
//        }
//        free(ivar);
//    }
//    return self;
//}


@end





////用户授信记录 NSUserDefaults
//#define User_Credit_Record_Info_UserDefaults @"User_Credit_Record_Info_UserDefaults"

@implementation FPUserCreditRecordInfo

+ (BOOL)supportsSecureCoding {
 
    return YES;
}

static id _sharedUserCreditRecordInfo;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    
    @synchronized(self) {
        
        if (_sharedUserCreditRecordInfo == nil) {
            
            _sharedUserCreditRecordInfo = [super allocWithZone:zone];
        }
    }
    return _sharedUserCreditRecordInfo;
}

+ (instancetype)sharedCreditRecordInfo {
    
    @synchronized(self){
        
        if(_sharedUserCreditRecordInfo == nil){
            
            _sharedUserCreditRecordInfo = [[self alloc] init];
        }
    }
    return _sharedUserCreditRecordInfo;
}

- (id)copyWithZone:(NSZone *)zone {
    
    return _sharedUserCreditRecordInfo;
}

+ (JSONKeyMapper *)keyMapper {
    
    return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"ID" : @"id"}];
}

+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    unsigned int count;
    Ivar *ivar = class_copyIvarList([self class], &count);
   
    for (int i = 0; i < count; i ++) {
    
        Ivar iva = ivar[i];
        const char *name = ivar_getName(iva);
        NSString *strName = [NSString stringWithUTF8String:name];
        //利用KVC取值
        id value = [self valueForKey:strName];
        [aCoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    
    if (self = [super init]) {
        unsigned int count = 0;
        Ivar *ivar = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i++) {
            Ivar iva = ivar[i];
            const char *name = ivar_getName(iva);
            NSString *strName = [NSString stringWithUTF8String:name];
            //进行解档取值
            id value = [aDecoder decodeObjectForKey:strName];
            //利用KVC对属性赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;
}

+ (void)saveUserCreditRecordInfo:(NSArray *)list {
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Credit_Record_Info_UserDefaults];

    // 归档并写入文件（iOS 11+ 推荐方法）
    NSError *error = nil;
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:list requiringSecureCoding:NO error:&error];
    BOOL result = [data writeToFile:filePath options:NSDataWritingAtomic error:nil];
    if (result) {
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
}

+ (NSArray *)getUserCreditRecordInfo {
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Credit_Record_Info_UserDefaults];
    
//    NSData *data = [NSData dataWithContentsOfFile:filePath];
    
    NSData *retrievedData = [NSData dataWithContentsOfFile:filePath];

    NSError *decodeError = nil;
    NSSet *allowedClasses = [NSSet setWithObjects:[NSArray class], [FPUserCreditRecordInfo class], nil];

    NSArray *unarchivedArray = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowedClasses fromData:retrievedData error:&decodeError];

    if (decodeError) {
        NSLog(@"解档失败: %@", decodeError.localizedDescription);
        
        return @[];
    } else {
        NSLog(@"解档成功: %@", unarchivedArray);
        
        return unarchivedArray;
    }
}

@end






@implementation FPUserLoanInfo

+ (BOOL)supportsSecureCoding {
 
    return YES;
}

static id _sharedUserLoanInfo;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    
    @synchronized(self) {
        
        if (_sharedUserLoanInfo == nil) {
            
            _sharedUserLoanInfo = [super allocWithZone:zone];
        }
    }
    return _sharedUserLoanInfo;
}

+ (instancetype)sharedUserLoanInfo {
    
    @synchronized(self){
        
        if(_sharedUserLoanInfo == nil){
            
            _sharedUserLoanInfo = [[self alloc] init];
        }
    }
    return _sharedUserLoanInfo;
}

- (id)copyWithZone:(NSZone *)zone {
    
    return _sharedUserLoanInfo;
}

+ (JSONKeyMapper *)keyMapper {
    
    return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"ID" : @"id"}];
}

+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    unsigned int count;
    Ivar *ivar = class_copyIvarList([self class], &count);
   
    for (int i = 0; i < count; i ++) {
    
        Ivar iva = ivar[i];
        const char *name = ivar_getName(iva);
        NSString *strName = [NSString stringWithUTF8String:name];
        //利用KVC取值
        id value = [self valueForKey:strName];
        [aCoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    
    if (self = [super init]) {
        unsigned int count = 0;
        Ivar *ivar = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i++) {
            Ivar iva = ivar[i];
            const char *name = ivar_getName(iva);
            NSString *strName = [NSString stringWithUTF8String:name];
            //进行解档取值
            id value = [aDecoder decodeObjectForKey:strName];
            //利用KVC对属性赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;
}

+ (void)saveUserLoanInfo:(NSArray *)list {
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Loan_Info_UserDefaults];
    
    NSError *error = nil;
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:list requiringSecureCoding:NO error:&error];
    BOOL result = [data writeToFile:filePath options:NSDataWritingAtomic error:nil];
    if (result) {
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
}


+ (NSArray *)getUserLoanInfo {
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Loan_Info_UserDefaults];
    
//    NSData *data = [NSData dataWithContentsOfFile:filePath];
    
    NSData *retrievedData = [NSData dataWithContentsOfFile:filePath];

    NSError *decodeError = nil;
    NSSet *allowedClasses = [NSSet setWithObjects:[NSArray class], [FPUserLoanInfo class], nil];

    NSArray *unarchivedArray = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowedClasses fromData:retrievedData error:&decodeError];

    if (decodeError) {
        NSLog(@"解档失败: %@", decodeError.localizedDescription);
        
        return @[];
    } else {
        NSLog(@"解档成功: %@", unarchivedArray);
        
        return unarchivedArray;
    }
}


@end







@implementation FPUserBankCardInfo

+ (BOOL)supportsSecureCoding {
 
    return YES;
}

static id _sharedBankCardInfo;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    
    @synchronized(self) {
        
        if (_sharedBankCardInfo == nil) {
            
            _sharedBankCardInfo = [super allocWithZone:zone];
        }
    }
    return _sharedBankCardInfo;
}

+ (instancetype)sharedBankCardInfo {
    
    @synchronized(self){
        
        if(_sharedBankCardInfo == nil){
            
            _sharedBankCardInfo = [[self alloc] init];
        }
    }
    return _sharedBankCardInfo;
}

- (id)copyWithZone:(NSZone *)zone {
    
    return _sharedBankCardInfo;
}

+ (JSONKeyMapper *)keyMapper {
    
    return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"ID" : @"id"}];
}

+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    unsigned int count;
    Ivar *ivar = class_copyIvarList([self class], &count);
   
    for (int i = 0; i < count; i ++) {
    
        Ivar iva = ivar[i];
        const char *name = ivar_getName(iva);
        NSString *strName = [NSString stringWithUTF8String:name];
        //利用KVC取值
        id value = [self valueForKey:strName];
        [aCoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    
    if (self = [super init]) {
        unsigned int count = 0;
        Ivar *ivar = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i++) {
            Ivar iva = ivar[i];
            const char *name = ivar_getName(iva);
            NSString *strName = [NSString stringWithUTF8String:name];
            //进行解档取值
            id value = [aDecoder decodeObjectForKey:strName];
            //利用KVC对属性赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;
}

+ (void)saveUserBankCardInfo:(NSArray *)list {
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Bank_Card_Info_UserDefaults];
    
    NSError *error = nil;
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:list requiringSecureCoding:NO error:&error];
    BOOL result = [data writeToFile:filePath options:NSDataWritingAtomic error:nil];
    if (result) {
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
}

+ (NSArray *)getUserBankCardInfo {
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Bank_Card_Info_UserDefaults];
    
//    NSData *data = [NSData dataWithContentsOfFile:filePath];
    
    NSData *retrievedData = [NSData dataWithContentsOfFile:filePath];

    NSError *decodeError = nil;
    NSSet *allowedClasses = [NSSet setWithObjects:[NSArray class], [FPUserBankCardInfo class], nil];

    NSArray *unarchivedArray = [NSKeyedUnarchiver unarchivedObjectOfClasses:allowedClasses fromData:retrievedData error:&decodeError];

    if (decodeError) {
        NSLog(@"解档失败: %@", decodeError.localizedDescription);
        
        return @[];
    } else {
        NSLog(@"解档成功: %@", unarchivedArray);
        
        return unarchivedArray;
    }
}



@end



















@implementation FPUserInfoModel

+ (BOOL)supportsSecureCoding {
 
    return YES;
}

static id _sharedUserInfo;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    
    @synchronized(self) {
        
        if (_sharedUserInfo == nil) {
            
            _sharedUserInfo = [super allocWithZone:zone];
        }
    }
    return _sharedUserInfo;
}

+ (instancetype)sharedUserInfo {
    
    @synchronized(self){
        
        if(_sharedUserInfo == nil){
            
            _sharedUserInfo = [[self alloc] init];
        }
    }
    return _sharedUserInfo;
}

- (id)copyWithZone:(NSZone *)zone {
    
    return _sharedUserInfo;
}

+ (JSONKeyMapper *)keyMapper {
    
    return [[JSONKeyMapper alloc] initWithModelToJSONDictionary:@{@"ID" : @"id"}];
}

+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    unsigned int count;
    Ivar *ivar = class_copyIvarList([self class], &count);
   
    for (int i = 0; i < count; i ++) {
    
        Ivar iva = ivar[i];
        const char *name = ivar_getName(iva);
        NSString *strName = [NSString stringWithUTF8String:name];
        //利用KVC取值
        id value = [self valueForKey:strName];
        [aCoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    
    if (self = [super init]) {
        unsigned int count = 0;
        Ivar *ivar = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i++) {
            Ivar iva = ivar[i];
            const char *name = ivar_getName(iva);
            NSString *strName = [NSString stringWithUTF8String:name];
            //进行解档取值
            id value = [aDecoder decodeObjectForKey:strName];
            //利用KVC对属性赋值
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;
}

// 获取所有属性名 和 类型
- (NSDictionary<NSString *, NSString *> *)getAllPropertiesWithTypes {
    unsigned int count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    
    NSMutableDictionary *propertyInfo = [NSMutableDictionary dictionary];
    for (unsigned int i = 0; i < count; i++) {
        const char *propertyName = property_getName(properties[i]);
        const char *attributes = property_getAttributes(properties[i]);
        [propertyInfo setObject:[NSString stringWithUTF8String:attributes] forKey:[NSString stringWithUTF8String:propertyName]];
    }
    
    free(properties);
    return propertyInfo;
}

// 获取所有属性名
- (NSArray<NSString *> *)getAllProperties {
    unsigned int count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    
    NSMutableArray *propertyNames = [NSMutableArray array];
    for (unsigned int i = 0; i < count; i++) {
        const char *propertyName = property_getName(properties[i]);
        [propertyNames addObject:[NSString stringWithUTF8String:propertyName]];
    }
    
    free(properties);
    return propertyNames;
}

#pragma mark - 获取用户信息
+ (void)getUserInfoWithSuccess:(void (^)(FPUserInfoModel * _Nonnull))success failure:(void (^)(NSError * _Nonnull))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:GET_USER_INFO_URL_V2] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        FPUserInfoModel *model = [[FPUserInfoModel alloc] initWithDictionary:[object objectForKey:@"data"] error:&error];
        
        model.phone = [FPUserModel AES256Decrypt:model.phone];
        model.idcardNumber = [FPUserModel AES256Decrypt:model.idcardNumber];
        
        if (success) {
            
            [FPUserInfoModel saveUserInfo:model];
            [FPUserLoanInfo saveUserLoanInfo:model.loan];
            [FPUserCreditRecordInfo saveUserCreditRecordInfo:model.creditRecord];
            [FPUserBankCardInfo saveUserBankCardInfo:model.userBankCard];
            
            success(model);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}


#pragma mark - 上传用户信息
+ (void)updateUserInfoWithParam:(NSDictionary *)param success:(void (^)(NSString *msg, NSInteger code))success failure:(void (^)(NSError *error))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:UPDATE_USER_INFO_URL_v2] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
//        FPUserInfoModel *model = [[FPUserInfoModel alloc] initWithDictionary:[object objectForKey:@"data"] error:&error];
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        NSString *message = [object objectForKey:@"msg"];
        
        if (success) {
            
//            [FPUserInfoModel saveUserInfo:model];
            
            success(message , httpCode);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 上传用户信息
+ (void)updateAdvertUserInfoWithParam:(NSDictionary *)param success:(void (^)(NSString *msg, NSInteger code))success failure:(void (^)(NSError *error))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:SAVE_USER_INFO_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
//        FPUserInfoModel *model = [[FPUserInfoModel alloc] initWithDictionary:[object objectForKey:@"data"] error:&error];
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        NSString *message = [object objectForKey:@"msg"];
        
        if (success) {
            
//            [FPUserInfoModel saveUserInfo:model];
            
            success(message , httpCode);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 留资后 服务端查询数据使用
+ (void)outPushWithParam:(NSDictionary *)param success:(void (^)(NSString *msg, NSInteger code))success failure:(void (^)(NSError *error))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:OUT_PUSH_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];

        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        NSString *message = [object objectForKey:@"msg"];
        
        if (success) {
            success(message , httpCode);
        }
        
    } failure:^(NSError *error) {
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 检查是否为真实客户
+ (void)outIdWithParam:(NSDictionary *)param success:(void (^)(NSString *webUrl, NSString *msg, NSInteger code))success failure:(void (^)(NSError *error))failure{
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:OUT_lD_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];

        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        NSString *webUrl = [object objectForKey:@"data"];
        NSString *message = [object objectForKey:@"msg"];
        
        if (success) {
            success(webUrl, message, httpCode);
        }
        
    } failure:^(NSError *error) {
        if (failure) {
            failure(error);
        }
    }];
}

+ (void)saveUserInfo:(FPUserInfoModel *)model {
    
    // 归档路径
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Info_UserDefaults];
    // 归档
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model requiringSecureCoding:NO error:nil];
    BOOL result = [data writeToFile:filePath options:NSDataWritingAtomic error:nil];
    if (result) {
        NSLog(@"归档成功");
    }else{
        NSLog(@"归档失败");
    }
}

+ (void)checkUserProfileInfoSuccess:(void (^)(NSInteger, NSString * _Nonnull , FPUserInfoModel *))success failure:(void (^)(NSError * _Nonnull))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:USER_INFO_CHECK_URL] parameters:@{} type:HttpRequestTypeGet success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
  
        FPUserInfoModel *model = [[FPUserInfoModel alloc] initWithDictionary:[object objectForKey:@"data"] error:&error];
        
        if (success) {
            
            success(httpCode , message , model);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

+ (void)checkMatchProductsParam:(FPUserInfoModel *)userInfo isHome:(BOOL)isHome success:(void (^)(NSInteger, NSString * _Nonnull, FPUserInfoModel * _Nonnull))success failure:(void (^)(NSError * _Nonnull))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
    
    NSString *URLString = [MAIN_URL stringByAppendingString:MATCH_HOME_PRODUCT_URL];
    
    if (!isHome) {
        
        URLString = [MAIN_URL stringByAppendingString:MATCH_PRODUCT_URL];
        
        [param setValue:userInfo.maritalStatus forKey:@"maritalStatus"];
        [param setValue:userInfo.educationalAttainment forKey:@"educationalAttainment"];
        [param setValue:userInfo.city forKey:@"city"];
    //    [param setValue:@"36" forKey:@"city"];
        
        [param setValue:userInfo.address forKey:@"address"];
        [param setValue:userInfo.occupation forKey:@"occupation"];
        
        [param setValue:userInfo.individualLicense forKey:@"individualLicense"];
        [param setValue:userInfo.monthlyIncome forKey:@"monthlyIncome"];
        [param setValue:userInfo.accumulationFund forKey:@"accumulationFund"];
        [param setValue:userInfo.socialSecurity forKey:@"socialSecurity"];
        [param setValue:userInfo.existRoom forKey:@"existRoom"];
        
        [param setValue:userInfo.vehicleCondition forKey:@"vehicleCondition"];
        [param setValue:userInfo.commercialInsurance forKey:@"commercialInsurance"];
        [param setValue:userInfo.sesameSeeds forKey:@"sesameSeeds"];
        [param setValue:userInfo.creditCardLimit forKey:@"creditCardLimit"];
        [param setValue:userInfo.creditCardAmount forKey:@"creditCardAmount"];
        
        NSString *num = [FPUserModel AES256Encrypt:userInfo.phone];
        [param setObject:num forKey:@"customerPhone"];
        [param setObject:@"-1" forKey:@"customerId"];
    }
    
    
    
    
    [[APIClient sharedInstance] requestWithURLString:URLString parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        
        FPUserInfoModel *model = [[FPUserInfoModel alloc] initWithDictionary:[object objectForKey:@"data"] error:&error];
        
//        NSArray *list = [FPProducts arrayOfModelsFromDictionaries:[object objectForKey:@"data"][@"products"] error:&error];
        
        if (success) {
            
            success(httpCode , message , model);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}


@end














@implementation FPUserModel

+ (BOOL)supportsSecureCoding {
 
    return YES;
}

+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    
    return YES;
}


+ (instancetype)sharedUser {
    
    static FPUserModel *sharedUser = nil;
    static dispatch_once_t onceToken_user;
    dispatch_once(&onceToken_user, ^{
        
        sharedUser = [[FPUserModel alloc] init];
    });
    
    return sharedUser;
}

#pragma mark - 注销账号
+ (void)clearAccountWithID:(NSString *)userID success:(void (^)(NSString * _Nonnull, NSInteger))success failure:(void (^)(NSError * _Nonnull))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
//    [param setObject:userID forKey:@"id"];
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:CLEAR_ACCOUNT_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *str = [object objectForKey:@"msg"];
        
        if (success) {
            
            success(str , httpCode);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 版本检测
+ (void)getApplicationVersionInfoSuccess:(void (^)(NSString * _Nonnull, NSInteger, NSString * _Nonnull , NSString * _Nonnull , NSString * _Nonnull , NSArray * _Nonnull , BOOL))success failure:(void (^)(NSError * _Nonnull))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
//    [param setObject:@"ipa" forKey:@"appType"];
//    [param setObject:@"1" forKey:@"type"];  // 1:iOS  2:Android
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:APP_VERSION_INFO_URL] parameters:param type:HttpRequestTypeGet success:^(id responseObject, NSString *msg, NSInteger code) {
         
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *str = [object objectForKey:@"data"][@"version"];
        
        NSString *urlStr = [object objectForKey:@"data"][@"url"];
        
        NSString *appSize = [object objectForKey:@"data"][@"appSize"];
        
//        NSString *contentStr = [object objectForKey:@"data"][@"content"];
//        
//        NSInteger force = [[object objectForKey:@"data"][@"isForce"] integerValue];
        
        NSString *manualURL = [object objectForKey:@"data"][@"shareBaseUrl"];
        
        NSArray *temp;
        
        BOOL ret = YES;
        
        if (success) {
            
            success(str , httpCode , urlStr , manualURL , appSize , temp , ret);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 活体检测 FinAuth 获取token
+ (void)getFinAuthFaceTokenSuccess:(void (^)(NSInteger, NSString * _Nonnull, NSString * _Nonnull , NSString * , NSString * , NSString *))success failure:(void (^)(NSError * _Nonnull))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:GET_FINAUTH_TOKEN_URL] parameters:@{} type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        
        NSString *token;
        NSString *province;
        NSString *cityName;
        NSString *cityID;
        
        if (code == 200) {
            
            token    = [object objectForKey:@"data"][@"biz_token"];
            province = [object objectForKey:@"data"][@"province"];
            cityName = [object objectForKey:@"data"][@"cityName"];
            cityID   = [object objectForKey:@"data"][@"id"];
        }
        
        if (success) {
            
            success(httpCode , message , token , province , cityName , cityID);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

 #pragma mark -  获取验证码
+ (void)getMessageCodeWithPhoneNumber:(NSString *)phoneNumber success:(void (^)(BOOL isSuccess, NSString *message, NSInteger code))success failure:(void (^)(NSError *error))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
    [param setObject:phoneNumber forKey:@"phone"];
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:GET_SMS_CODE_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSString *str = [object objectForKey:@"msg"];
        
        if (success) {
            
            success(YES, str, code);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 阿里一键登录token 传给后端
+ (void)loginWithAccessToken:(NSString *)token success:(void (^)(NSString * _Nonnull, NSInteger , BOOL))success failure:(void (^)(NSError * _Nonnull))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
    [param setObject:token forKey:@"accessToken"];
    [param setObject:@"8" forKey:@"channel"];
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:VERIFY_MOBILE_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        
        NSString *token;
        NSString *headUrl;
        BOOL ret = NO;
        
        if ([object[@"data"] isKindOfClass:NSDictionary.class]) {
            
            token = [object objectForKey:@"data"][@"token"];
            headUrl = [object objectForKey:@"data"][@"headUrl"];
            ret = [[object objectForKey:@"data"][@"registered"] boolValue];
        }
        
        [FPUserModel setUserToken:token];
        [FPUserModel setHeadURL:headUrl];
        [FPUserModel setFirstRegisterUser:ret];
        
        if (success) {
            
            success(message , httpCode , ret);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 验证码登录
+ (void)loginWithPhoneNumber:(NSString *)phoneNumger code:(NSString *)code success:(void (^)(FPUserModel * _Nonnull, NSString * _Nonnull, NSInteger , BOOL ))success failure:(void (^)(NSError * _Nonnull))failure {
    
    NSMutableDictionary *param = APIClient.creatAPIDictionary;
    [param setObject:phoneNumger forKey:@"phone"];
    [param setObject:code forKey:@"code"];
    [param setObject:@"8" forKey:@"channel"];
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:LOGIN_SMS_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        FPUserModel *model = [[FPUserModel alloc] initWithDictionary:[object objectForKey:@"data"] error:&error];
        
        [FPUserModel setUserToken:model.token];
        [FPUserModel setHeadURL:model.headUrl];
        [FPUserModel setFirstRegisterUser:model.registered];
        
        BOOL firstRegist = model.registered;
        
        if (success) {
            
            success(model, msg, code , firstRegist);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 退出登录
+ (void)logoutSuccess:(void (^)(NSString * _Nonnull, NSInteger))success failure:(void (^)(NSError * _Nonnull))failure {
   
   NSMutableDictionary *param = APIClient.creatAPIDictionary;
   
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:LOGOUT_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
       
       NSError *error;
       
       id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
       
       NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
       
       NSString *str = [object objectForKey:@"msg"];
       
       if (success) {
           
           success(str , httpCode);
       }
       
   } failure:^(NSError *error) {
       
       if (failure) {
           failure(error);
       }
   }];
}


+ (void)setFirstRegisterUser:(BOOL)firstRegister {
    
    [NSUserDefaults.standardUserDefaults setObject:@(firstRegister) forKey:USER_FIRST_REGISTER];
    [NSUserDefaults.standardUserDefaults synchronize];
}

+ (BOOL)firstRegisterUser {
    
    return [[NSUserDefaults.standardUserDefaults objectForKey:USER_FIRST_REGISTER] boolValue];
}


+ (void)setHeadURL:(NSString *)headURL {
    
    [NSUserDefaults.standardUserDefaults setObject:headURL forKey:HEAD_URL];
    [NSUserDefaults.standardUserDefaults synchronize];
}

+ (NSString *)globalHeadURL {
    
    return [NSUserDefaults.standardUserDefaults objectForKey:HEAD_URL];
}


+ (void)setUserToken:(NSString *)token {
    
    [NSUserDefaults.standardUserDefaults setObject:token forKey:GLOBAL_TOKEN];
    [NSUserDefaults.standardUserDefaults synchronize];
}


+ (NSString *)globalToken {
    
    return [NSUserDefaults.standardUserDefaults objectForKey:GLOBAL_TOKEN];
}


+ (void)removeToken {
    
    [NSUserDefaults.standardUserDefaults removeObjectForKey:GLOBAL_TOKEN];
    [NSUserDefaults.standardUserDefaults synchronize];
}

#pragma mark - 从本地获取model
+ (FPUserInfoModel *)getUserInfoModel {
 
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [path stringByAppendingPathComponent:User_Info_UserDefaults];
    
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    FPUserInfoModel *model = [NSKeyedUnarchiver unarchivedObjectOfClass:FPUserInfoModel.class fromData:data error:nil];
    
    return model;
}

#pragma mark - 意见反馈
+ (void)submitFeedBackWithParam:(NSDictionary *)param success:(void (^)(NSInteger code , NSString *message))success failure:(void (^)(NSError *error))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:FEEDBACK_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        
        if (success) {
            
            success(httpCode , message);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 获取服务器当前时间
+ (void)getServiceCurrenTimeSuccess:(void (^)(NSInteger, NSString * _Nonnull, NSString * _Nonnull))success failure:(void (^)(NSError * _Nonnull))failure {
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:GET_SERVICE_CURREN_TIME_URL] parameters:@{} type:HttpRequestTypeGet success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        
        NSString *time = [object objectForKey:@"data"];
        
        if (success) {
            
            success(httpCode , message , time);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}

#pragma mark - 人脸认证
+ (void)faceAuthenticationWithParam:(NSDictionary *)param success:(void (^)(NSString *message, NSInteger code , NSString *faceUrl ,  NSInteger result, NSString *serialNo, NSString *serialVersionUID, NSString *type))success failure:(void (^)(NSError *error))failure{
    
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:USER_FACE_AUTHENTICATION_URL] parameters:param type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        
        NSString *serialNo , *serialVersionUID , *type , *faceUrl;
        NSInteger result = 0;
        
        if ([object isKindOfClass:NSDictionary.class]) {
            
            if ([[object objectForKey:@"data"] isKindOfClass:NSDictionary.class]) {
             
                faceUrl   = [object objectForKey:@"data"][@"faceUrl"];
                serialNo      = [object objectForKey:@"data"][@"serialNo"];
                serialVersionUID   = [object objectForKey:@"data"][@"serialVersionUID"];
                type   = [object objectForKey:@"data"][@"type"];
                result     = [[object objectForKey:@"data"][@"result"] integerValue];
            }
        }
        
        
        
        if (success) {
            
            success(message , httpCode , faceUrl , result , serialNo , serialVersionUID, type);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}
+ (void)realNameAuthResultWithParam:(NSDictionary *)param success:(void (^)(NSString *message, NSInteger code,NSInteger result))success failure:(void (^)(NSError *error))failure{
    NSString *URLString = [APIClient getQueryURLStringWithParam:param URLString:USER_FACE_AUTHENTICATIONRESULT_URL];
    [[APIClient sharedInstance] requestWithURLString:[MAIN_URL stringByAppendingString:URLString] parameters:@{} type:HttpRequestTypePost success:^(id responseObject, NSString *msg, NSInteger code) {
        
        NSError *error;
        
        id object = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
        
        NSInteger httpCode = [[object objectForKey:@"code"] integerValue];
        
        NSString *message = [object objectForKey:@"msg"];
        NSInteger result = 0;
        if ([object isKindOfClass:NSDictionary.class]) {
            
            if ([[object objectForKey:@"data"] isKindOfClass:NSDictionary.class]) {
                result = [[[object objectForKey:@"data"] objectForKey:@"result"] intValue];
            }
        }
        
        if (success) {
            success(message , httpCode , result);
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
    }];
}
#pragma mark - 401处理
- (void)loginInvalid {
    
    FPUserInfoModel *model = FPUserInfoModel.sharedUserInfo;
    
    unsigned int count;
    // 获取所有属性
    objc_property_t *properties = class_copyPropertyList(model.class, &count);
    
    // 遍历属性列表
    for (unsigned int i = 0; i < count; i++) {
        objc_property_t property = properties[i];
        
        // 获取属性的名称
        const char *propertyName = property_getName(property);
        NSString *propertyNameString = [NSString stringWithUTF8String:propertyName];
        
        if (![propertyNameString isEqualToString:@"succeed"]) {
            
            [model setValue:nil forKey:propertyNameString];
        }
    }
    
    free(properties); // 释放内存
    
    [FPUserInfoModel saveUserInfo:model];
    
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath1 = [path stringByAppendingPathComponent:User_Info_UserDefaults];
    
    [[NSFileManager defaultManager] removeItemAtPath:filePath1 error:nil];
    
    [FPUserModel removeToken];
    
    NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
    NSDictionary *dic = userDefaults.dictionaryRepresentation;
    
    for (NSString *key in dic) {
        
        [userDefaults removeObjectForKey:key];
    }
    
    [userDefaults synchronize];
    
    //
//    [NSUserDefaults.standardUserDefaults removeObjectForKey:First_Entry_Application_Key];
//    [NSUserDefaults.standardUserDefaults synchronize];
}

// 解密
+ (NSString *)AES256Decrypt:(NSString *)text {
    
    if (text.length > 0) {
        
        NSString *key = @"rcb4p16wb9zj85q2";
        text = [MIUAES MIUAESDecrypt:text mode:kCCModeECB key:key keySize:MIUKeySizeAES128 iv:nil padding:MIUCryptorPKCS7Padding];
        
        return text;
    }
    
    return nil;
}

// 加密
+ (NSString *)AES256Encrypt:(NSString *)text { 
    
    if (text.length > 0) {
     
        NSString *key = @"rcb4p16wb9zj85q2";
        NSString *str = [MIUAES MIUAESEncrypt:text mode:MIUModeECB key:key keySize:(MIUKeySizeAES128) iv:nil padding:(MIUCryptorPKCS7Padding)];
        
        return str;
    }
    
    return nil;
}


@end
